import { IColumns, getRandomId } from "../../ExcelStore";
import { FieldTypeName } from "../celltypes/FieldCellType";

const toCells = (range) => {
    const cells: GC.Spread.Sheets.CellRange[] = [];
    const { row, rowCount, sheet } = range;
    let { col } = range;
    let { colCount } = range;
    if (colCount === -1) {
        colCount = sheet.getColumnCount() + 1;
    }
    if (col === -1) {
        col = 0;
    }
    for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
        const currentRow = row + rowIndex;
        for (let colIndex = 0; colIndex < colCount; colIndex++) {
            const currentCol = col + colIndex;
            if (currentCol > -1) {
                cells.push(sheet.getCell(currentRow, currentCol));
            }
        }
    }
    return cells;
}

const isSameTypeColumn = (col1: IColumns, col2: IColumns) => {
    if (col1.typeName === col2.typeName) {
        if (col1.typeName === FieldTypeName.Int) {
            return true;
        } else if (col1.typeName === FieldTypeName.Text) {
            return col1.length <= col2.length;
        } else if (col1.typeName === FieldTypeName.Float || col1.typeName === FieldTypeName.Thousand || col1.typeName === FieldTypeName.Money) {
            return col1.length <= col2.length && col1.qfws <= col2.qfws;
        } else if (col1.typeName === FieldTypeName.Browser) {
            return col1.type === col2.type && col1.dbtype === col2.dbtype;
        } else if (col1.typeName === FieldTypeName.DateTime) {
            return col1.type === col2.type;
        }
        return true;
    } else {
        return false;
    }
}
export default {
    canUndo: true,
    execute: (context, options, isUndo) => {
        context.suspendPaint();
        try {
            const { sheet, sheetName, sourceSheet, cellRange, table, dataSource, backColumn, setChangedValue, sourceRange, value } = options;
            
            const targetCells = toCells({ ...cellRange, sheet });
            if (isUndo) {

            } else {
                const { row: startRow } = table.dataRange();
                const datas: any[] = dataSource.getValue('datas');
                options.oldValue = targetCells.map(cell => cell.value());
                options.oldText = targetCells.map(cell => cell.text());
                if (sourceSheet && sourceRange) {
                    const sourceCells = toCells({ ...sourceRange, sheet, sourceSheet });
                    if (sourceCells.length === 1) { // 一个单元格时，所有目标单元格都要粘贴
                        const [{ row, col }] = sourceCells;
                        const dataIndex = row - startRow;
                        const sourceColumn: IColumns = backColumn[col];
                        if (dataIndex > -1 && dataIndex < datas.length) {
                            const sourceData = datas[dataIndex];
                            const newValue = sourceData[sourceColumn.column];
                            const newValueSpan = sourceData[`${sourceColumn.column}span`];
                            targetCells.forEach(targetCell => {
                                const { row: targetRow, col: targetCol } = targetCell;
                                const targetColumn: IColumns = backColumn[targetCol];

                                if (targetColumn&&targetColumn.editable === '1' && isSameTypeColumn(sourceColumn, targetColumn)) {
                                    const targetDataIndex = targetRow - startRow;
                                    if (targetDataIndex > -1 && targetDataIndex < datas.length) {
                                        const targetData = datas[targetDataIndex];
                                        const oldValueSpan = targetData[`${targetColumn.column}span`];
                                        targetData[targetColumn.column] = newValue;
                                        targetData[`${targetColumn.column}span`] = newValueSpan;
                                        setChangedValue(getRandomId(targetData), targetColumn, { sheet, row: targetRow, col: targetCol, newValue: newValueSpan, oldValue: oldValueSpan, sheetName,time:targetData["time"] });
                                    }
                                }
                            })
                        }
                    } else if (sourceCells.length > 1) { // 复制多个单元格时， 粘贴到目标区域的对应单元格
                        const { row: targetStartRow, col: targetStartCol } = cellRange;
                        const { row: sourceStartRow, col: sourceStartCol, rowCount: sourceRowCount, colCount: sourceColCount } = sourceRange;
                        const sourceMaxRow = sourceStartRow + sourceRowCount;
                        const sourceMaxCol = sourceStartCol + sourceColCount;
                        targetCells.forEach(targetCell => {
                            const { row: targetRow, col: targetCol } = targetCell;
                            const sourceRow = targetRow - targetStartRow + sourceStartRow;
                            const sourceCol = targetCol - targetStartCol + sourceStartCol;
                            if (sourceRow < sourceMaxRow && sourceCol <= sourceMaxCol) {
                                const sourceColumn: IColumns = backColumn[sourceCol];
                                const targetColumn: IColumns = backColumn[targetCol];
                                const sourceDataIndex = sourceRow - startRow;
                                const targetDataIndex = targetRow - startRow;

                                if (sourceDataIndex > - 1
                                    && sourceDataIndex < datas.length
                                    && targetDataIndex > -1
                                    && targetDataIndex < datas.length
                                    && targetColumn.editable === '1'
                                    && isSameTypeColumn(sourceColumn, targetColumn)) {
                                        
                                    const sourceData = datas[sourceDataIndex];
                                    const targetData = datas[targetDataIndex];
                                    const newValue = sourceData[sourceColumn.column];
                                    const newValueSpan = sourceData[`${sourceColumn.column}span`];
                                    const oldValue = targetData[`${targetColumn.column}span`];
                                    targetData[targetColumn.column] = newValue;
                                    targetData[`${targetColumn.column}span`] = newValueSpan;
                                    setChangedValue(getRandomId(targetData), targetColumn, { sheet, row: targetRow, col: targetCol, newValue: newValueSpan, oldValue, sheetName,time:targetData["time"] });
                                }
                            }
                        });
                    }
                } else {
                    if (value) {
                        const valueTr = value.split('\r\n');
                        const values: any[] = [];
                        valueTr.forEach(tr => {
                            const trValues: any[] = [];
                            tr.split('	').forEach(td => {
                                trValues.push(td);
                            })
                            values.push(trValues);
                        });
                        const { row: dataStartRow } = table.dataRange();
                        const { row: startRow, col: startCol } = cellRange;
                        const datas: any[] = dataSource.getValue('datas');
                        targetCells.forEach(targetCell => {
                            const { row: targetRow, col: targetCol } = targetCell;
                            const column = backColumn[targetCol];
                            const dataIndex = targetRow - dataStartRow;
                            if (column.editable === '1' && dataIndex > -1 && dataIndex < datas.length && column.typeName === FieldTypeName.Text) {
                                let newValue: string = (values[targetRow - startRow] || {})[targetCol - startCol] || '';
                                if (newValue && newValue.length > column.length) {
                                    return;
                                }
                                const data = datas[dataIndex];
                                const oldValue = data[`${column.column}span`];
                                data[column.column] = newValue;
                                data[`${column.column}span`] = JSON.stringify({ value: newValue });
                                setChangedValue(getRandomId(data), column, { sheet, row: targetRow, col: targetCol, newValue: data[`${column.column}span`], oldValue, sheetName,time:data["time"] });
                            }
                        })
                    }
                }
            }
        } catch (e) {
            if (!!(window.console && window.console.log)) {
                window.console.log(e);
            }
        }
        context.resumePaint();
    }
};